package hd.util.widget.listview.pinned;

import android.content.Context;
import android.graphics.Canvas;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ListAdapter;
import android.widget.ListView;

/**
 * 悬浮Header ListView
 * <p/>
 * Created by Haidy on 15/3/22.
 */
public class PinnedHeaderListView extends ListView {

    private static final int MAX_ALPHA = 255;
    private PinnedHeaderAdapter mAdapter;
    private boolean headerViewVisible = false;
    private View headerView;
    private int headerViewWidth;
    private int headerViewHeight;

    public PinnedHeaderListView(Context context) {
        this(context, null);
    }

    public PinnedHeaderListView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PinnedHeaderListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    public void configureHeaderView(int position) {
        if (headerView == null || null == mAdapter) {
            return;
        }
        int state = mAdapter.getPinnedHeaderState(position);
        switch (state) {
            case PinnedHeaderAdapter.PINNED_HEADER_GONE: {
                headerViewVisible = false;
                break;
            }
            case PinnedHeaderAdapter.PINNED_HEADER_VISIBLE: {
                mAdapter.configurePinnedHeader(headerView, position, MAX_ALPHA);
                if (headerView.getTop() != 0) {
                    headerView.layout(0, 0, headerViewWidth, headerViewHeight);
                }
                headerViewVisible = true;
                break;
            }
            case PinnedHeaderAdapter.PINNED_HEADER_PUSHED_UP: {
                View firstView = getChildAt(0);
                int bottom = firstView.getBottom();
                int headerHeight = headerView.getHeight();
                int y;
                int alpha;
                if (bottom < headerHeight) {
                    y = (bottom - headerHeight);
                    alpha = MAX_ALPHA * (headerHeight + y) / headerHeight;
                } else {
                    y = 0;
                    alpha = MAX_ALPHA;
                }
                mAdapter.configurePinnedHeader(headerView, position, alpha);
                if (headerView.getTop() != y) {
                    headerView.layout(0, y, headerViewWidth, headerViewHeight + y);
                }
                headerViewVisible = true;
                break;
            }
        }
    }

    /**
     * 设置HeaderView
     *
     * @param headerView header View
     */
    public void setHeaderView(View headerView) {
        this.headerView = headerView;
        AbsListView.LayoutParams lp = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        headerView.setLayoutParams(lp);
        setFadingEdgeLength(0);
        requestLayout();
    }

    @Override
    public void setAdapter(ListAdapter adapter) {
        super.setAdapter(adapter);
        this.mAdapter = (PinnedHeaderAdapter) adapter;
        this.setOnScrollListener((OnScrollListener) adapter);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (headerView != null) {
            measureChild(headerView, widthMeasureSpec, heightMeasureSpec);
            headerViewWidth = headerView.getMeasuredWidth();
            headerViewHeight = headerView.getMeasuredHeight();
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (headerView != null) {
            headerView.layout(0, 0, headerViewWidth, headerViewHeight);
            configureHeaderView(getFirstVisiblePosition());
        }
    }

    @Override
    protected void dispatchDraw(@NonNull Canvas canvas) {
        super.dispatchDraw(canvas);
        if (headerViewVisible) {
            drawChild(canvas, headerView, getDrawingTime());
        }
    }
}
